/* ---------------------------------------------------------------------------------------------
 *
 *            Capital Alliance Software Confidential Proprietary
 *            (c) Copyright CAS 201{x}, All Rights Reserved
 *                          www.pekall.com
 *
 * ----------------------------------------------------------------------------------------------
 */

package com.pekall.myDictionary.screens;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

import com.pekall.myDictionary.core.DictCnDictSource;
import com.pekall.myDictionary.core.DictSource;
import com.pekall.myDictionary.core.ICiBaDictSource;
import com.pekall.myDictionary.utils.SQLiteNewWords;
import com.pekall.myDictionary.utils.Utils;

public class ExplainScreen extends Activity implements DictSource.OnUpdateNotifyListener,
        PanelSwitcher.OnMoveNotifyListener, OnItemClickListener, OnClickListener/*
                                                                                 * ,
                                                                                 * OnTouchListener
                                                                                 */{

    private static final int DEFAULT_PLAY_AUDIO_TIME_OUT = 10000;

    private static final int WHAT_NETWORK_EXPLAIN_START = 0;

    private static final int WHAT_NETWORK_EXPLAIN_DONE = 1;

    private static final int WHAT_PLAY_AUDIO_START = 0;

    private static final int WHAT_PLAY_AUDIO_DONE = 1;

    private static final int WHAT_PLAY_AUDIO_TIMEOUT = 2;

    private TextView mWord;

    private PronunciationView mPron;

    private TextView mExplain;

    private Button mMoreBtn;

    // private Button mAddNewWordBtn;
    private ViewGroup mStatus;

    private List<DictSource> mDictSources = new ArrayList<DictSource>();

    private List<Word> mWordWebs = new ArrayList<Word>();

    private String key;

    private Context mContext;

    private PackageManager mPackageManager;

    private boolean isCnOrEn;

    private SQLiteNewWords mSQL;

    private String mNewWord;

    public static final int DIALOG_WAITING = 10;

    private static final String TAG = ExplainScreen.class.getSimpleName();

    // private GestureDetector mGestureDetector;
    private ProgressDialog progressDialog;

    private MediaPlayer player;

    private int PANEL_CURRENT = 0;

    private LayoutInflater mLayoutInflater;

    private static PanelSwitcher mPanelSwitcher;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.explain);
        mContext = this;

        mPackageManager = getPackageManager();

        mStatus = (ViewGroup) findViewById(R.id.status);
        mPanelSwitcher = (PanelSwitcher) findViewById(R.id.panelswitch);
        mPanelSwitcher.setOnMoveNotifyListener(this);
        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        player = new MediaPlayer();
        int max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        player.setVolume(max, max);
        mWord = (TextView) findViewById(R.id.word);

        // mAddNewWordBtn = (Button) findViewById(R.id.add_new_worddic);
        // mAddNewWordBtn.setOnClickListener(this);

        if (isWordMemoInstalled()) {
            // mAddNewWordBtn.setVisibility(View.VISIBLE);
        } else {
            // mAddNewWordBtn.setVisibility(View.GONE);
        }

        mPron = (PronunciationView) findViewById(R.id.pron);
        mExplain = (TextView) findViewById(R.id.expalin);
        mMoreBtn = (Button) findViewById(R.id.more);
        mMoreBtn.setOnClickListener(this);
        Intent intent = getIntent();
        if (intent.getData() != null) {
            String explain = intent.getData().toString();
            mNewWord = explain;
            setExplain(explain);
        } else {
            mWord.setText(R.string.msg_not_found);
            mWord.setTextSize(19);
            // mAddNewWordBtn.setVisibility(View.GONE);
            mPron.setVisibility(View.GONE);
            mExplain.setVisibility(View.GONE);
            key = intent.getStringExtra("key");
            mNewWord = key;
        }
        isCnOrEn = intent.getBooleanExtra("isCnOrEn", true);

        mLayoutInflater = LayoutInflater.from(this);
    }

    void setExplain(String explain) {

        int n = explain.indexOf('\t');
        if (n > 0) {
            key = explain.substring(0, n);
            mWord.setText(key);
        }
        int n1 = explain.indexOf('\t', n + 1);
        if (n1 > 0) {
            String pron = explain.substring(n + 1, n1);
            try {
                byte[] buffer = pron.getBytes("utf-8");
                boolean bigEndian = (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN);
                // 数组越界问题
                for (int i = 0; i < buffer.length - 1; i += 2) {
                    if (bigEndian) {
                        int uchar = ((buffer[i] & 0xff) << 8) + (buffer[i + 1] & 0xff);
                        uchar = translate(uchar);
                        buffer[i] = (byte) ((uchar >> 8) & 0xff);
                        buffer[i + 1] = (byte) (uchar & 0xff);
                    } else {
                        int uchar = ((buffer[i] & 0xff)) + ((buffer[i + 1] & 0xff) << 8);
                        uchar = translate(uchar);
                        buffer[i] = (byte) (uchar & 0xff);
                        buffer[i + 1] = (byte) ((uchar >> 8) & 0xff);
                    }
                }
                mPron.setText(String.format("[%s]", new String(buffer, "utf-8")));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            mPron.setVisibility(View.GONE);
            n1 = n;
        }

        mExplain.setText(explain.substring(n1 + 1));
    }

    private int translate(int uchar) {
        int newchar[] = {
                0x254, 0x251, 0x259, 0x28c, 0x275, 0xf0, 0x283, 0x2a4, 0x14b, 0x00e6
        };
        if (uchar >= '0' && uchar <= '9') {
            return newchar[uchar - '0'];
        } else {
            return uchar;
        }
    }

    public static class Word {
        public String source;

        public String key;

        public String pron = "";

        public String audio = "";

        public String definition = "";

        public List<Example> examples;

        public Word() {
        }

        public Word(String key, String definition) {
            this.key = key;
            this.definition = definition;
        }

        @Override
        public String toString() {
            return "Word [audio=" + audio + ", definition=" + definition + ", examples=" + examples
                    + ", key=" + key + ", pron=" + pron + ", source=" + source + "]";
        }

    }

    public static class Example {
        public String orig;

        public String trans;

        public String audio;

        public Example() {
        }

        @Override
        public String toString() {
            return "Example [audio=" + audio + ", orig=" + orig + ", trans=" + trans + "]";
        }

    }

    private void refleshWord() {
        mDictSources.clear();
        /*
         * www.dict.cn
         */
        DictSource mCnDictSource = new DictCnDictSource(mContext);
        mCnDictSource.setOnNotifyListener(ExplainScreen.this);
        mDictSources.add(mCnDictSource);

        /*
         * www.iciba.com
         */
        DictSource mDictSource = new ICiBaDictSource(mContext);
        mDictSource.setOnNotifyListener(ExplainScreen.this);
        mDictSources.add(mDictSource);
        WebTask task = new WebTask();
        task.execute();

    }

    public void addDict(int id) {
        LayoutInflater inflater = LayoutInflater.from(this);
        ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.word_item, null);
        layout.setId(id);
        mPanelSwitcher.addView(layout);
        mPanelSwitcher.onFinishInflate();
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(8, 8);
        params.leftMargin = 2;
        params.rightMargin = 2;
        Button btn1 = new Button(this);
        btn1.setId(id);
        if (id == 0) {
            btn1.setBackgroundResource(R.drawable.light);
        } else {
            btn1.setBackgroundResource(R.drawable.dark);
        }
        btn1.setLayoutParams(params);
        mStatus.addView(btn1);
    }

    private void changeStatus() {
        int panelCount = mPanelSwitcher.getChildCount();
        for (int i = 0; i < panelCount; i++) {
            Button btn1 = (Button) mStatus.findViewById(i);
            if (i == PANEL_CURRENT) {
                btn1.setBackgroundResource(R.drawable.light);
            } else {
                btn1.setBackgroundResource(R.drawable.dark);
            }
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_WAITING:
                progressDialog = new ProgressDialog(this);
                progressDialog.setMessage(getString(R.string.msg_wait));
                progressDialog.setIndeterminate(true);
                progressDialog.setCancelable(true);
                return progressDialog;
        }
        return null;
    }

    public class WebTask extends AsyncTask<String, Integer, Void> {
        @Override
        protected Void doInBackground(String... values) {
            // for (int i = 0; i < mDictSources.size(); i++) {
            // DictSource mDictSource = mDictSources.get(i);
            // refleshSource(mDictSource);
            // publishProgress(i);
            // }
            DictSource mDictSource;
            if (isCnOrEn) {
                mDictSource = mDictSources.get(0);
                refleshSource(mDictSource);
                publishProgress(0);
            } else {
                mDictSource = mDictSources.get(1);
                refleshSource(mDictSource);
                publishProgress(1);
                mDictSource = mDictSources.get(0);
                refleshSource(mDictSource);
                publishProgress(0);
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mNetworkExplainHandler.sendEmptyMessage(WHAT_NETWORK_EXPLAIN_START);

        }

        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            mStatus.removeAllViews();
            mPanelSwitcher.removeAllViews();
            mPanelSwitcher.onFinishInflate();
            for (int i = 0; i < mWordWebs.size(); i++) {
                addDict(i);
                View views = mPanelSwitcher.getView(i);
                Word word = mWordWebs.get(i);
                showDict(views, word);
            }
            mNetworkExplainHandler.sendEmptyMessage(WHAT_NETWORK_EXPLAIN_DONE);
            // mMoreBtn.setEnabled(true);
            mMoreBtn.setClickable(true);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
        }

        private void refleshSource(DictSource mDictSource) {
            String content = mDictSource.downloadSetContent(new String[] {
                key
            });

            if (!TextUtils.isEmpty(content)) {
                Word word = (Word) mDictSource.parseContent(content);
                if (word != null) {
                    mWordWebs.add(word);
                }
            }
        }
    }

    private void showDict(View v, final Word word) {

        TextView dict_source = (TextView) v.findViewById(R.id.dict_source);
        dict_source.setText("Powered by " + word.source);
        final ImageView audioBtn = (ImageView) v.findViewById(R.id.AudioPlayButton);
        if (!TextUtils.isEmpty(word.audio)) {
            audioBtn.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    playAudio(word.audio, audioBtn);
                }
            });

        } else {
            audioBtn.setVisibility(Button.GONE);
        }

        TextView keyText = (TextView) v.findViewById(R.id.Key);
        String keyValue = word.key;
        if (!TextUtils.isEmpty(keyValue)) {
            keyText.setText(Html.fromHtml(keyValue));
        }
        PronunciationView pronText = (PronunciationView) v.findViewById(R.id.Pronitem);
        String pronValue = word.pron;
        if (!TextUtils.isEmpty(pronValue)) {
            pronText.setText("[" + pronValue + "]");
        } else {
            pronText.setVisibility(View.GONE);
        }
        TextView definition = (TextView) v.findViewById(R.id.definition);
        if (!TextUtils.isEmpty(word.definition)) {
            definition.setText(word.definition);
        }
        LinearLayout exampleView = (LinearLayout) v.findViewById(R.id.examplelist);
        setExampleView(exampleView, word.examples);
    }

    private void setExampleView(ViewGroup parent, List<Example> examples) {
        for (int i = 0; i < examples.size(); i++) {
            View v = mLayoutInflater.inflate(R.layout.explain_item, parent, false);
            final Example example = examples.get(i);
            TextView text1 = (TextView) v.findViewById(R.id.text1);
            text1.setText(example.orig);
            TextView text2 = (TextView) v.findViewById(R.id.text2);
            text2.setText(example.trans);
            final ImageView audioBtn = (ImageView) v.findViewById(R.id.AudioPlayButton);
            if (!TextUtils.isEmpty(example.audio)) {
                audioBtn.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        playAudio(example.audio, audioBtn);
                    }
                });
            } else {
                audioBtn.setVisibility(Button.INVISIBLE);
            }
            parent.addView(v);
        }
    }

    private AudioManager mAudioManager;

    public void playAudio(String path, final ImageView audioBtn) {
        if (!Utils.isNetworkConnected(this)) {
            showNetworkNotAvailableToast();
            return;
        }

        try {
            player.reset();
            player.setDataSource(path);
            mPlayAudioHandler.sendEmptyMessage(WHAT_PLAY_AUDIO_START);
            mPlayAudioHandler.sendEmptyMessageDelayed(WHAT_PLAY_AUDIO_TIMEOUT,
                    DEFAULT_PLAY_AUDIO_TIME_OUT);
            player.setOnPreparedListener(new OnPreparedListener() {
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                    mPlayAudioHandler.sendEmptyMessage(WHAT_PLAY_AUDIO_DONE);
                    audioBtn.setImageResource(R.anim.speaker);
                }
            });
            player.setOnCompletionListener(new OnCompletionListener() {
                public void onCompletion(MediaPlayer mp) {
                    audioBtn.setImageResource(R.drawable.sound_none);
                }
            });

            player.setOnErrorListener(new OnErrorListener() {

                public boolean onError(MediaPlayer mp, int what, int extra) {
                    switch (what) {
                        case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                            Toast.makeText(mContext, mContext.getString(R.string.msg_audio_error),
                                    Toast.LENGTH_LONG).show();
                            mPlayAudioHandler.sendEmptyMessage(WHAT_PLAY_AUDIO_DONE);
                            break;
                        default:
                            mPlayAudioHandler.sendEmptyMessage(WHAT_PLAY_AUDIO_DONE);
                            break;
                    }
                    audioBtn.setImageResource(R.drawable.sound_none);
                    return false;
                }
            });
            player.prepareAsync();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class WordAdapter extends BaseAdapter {
        private LayoutInflater mFactory;

        private List<Example> mExamples;

        WordAdapter(Context context, List<Example> examples) {
            mFactory = LayoutInflater.from(context);
            mExamples = examples;
        }

        public int getCount() {
            return mExamples.size();
        }

        public Object getItem(int position) {
            return mExamples.get(position);
        }

        public long getItemId(int position) {
            return position;
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View v = convertView;
            if (v == null) {
                v = mFactory.inflate(R.layout.explain_item, parent, false);
            }
            final Example example = mExamples.get(position);
            TextView text1 = (TextView) v.findViewById(android.R.id.text1);
            text1.setText(example.orig);
            TextView text2 = (TextView) v.findViewById(android.R.id.text2);
            text2.setText(example.trans);
            final ImageView audioBtn = (ImageView) v.findViewById(R.id.AudioPlayButton);
            if (!TextUtils.isEmpty(example.audio)) {
                audioBtn.setOnClickListener(new OnClickListener() {
                    public void onClick(View v) {
                        playAudio(example.audio, audioBtn);
                    }
                });
            } else {
                audioBtn.setVisibility(Button.GONE);
            }
            return v;
        }
    }

    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }

    public void onClick(View v) {
        if (mMoreBtn == v) {
            // mMoreBtn.setEnabled(false);
            mMoreBtn.setClickable(false);
            mWordWebs.clear();
            refleshWord();

        }
        // else if (mAddNewWordBtn == v) {
        // mSQL = new SQLiteNewWords(this);
        // mSQL.save(mNewWord);
        // }
    }

    private boolean isWordMemoInstalled() {
        try {
            mPackageManager.getPackageInfo("com.pekall.wordmemo", PackageManager.GET_PROVIDERS);
            return true;
        } catch (NameNotFoundException e) {
            Log.d(TAG, "wordmemo not found");
            return false;
        }
    }

    @Override
    public void onBackPressed() {
        moveRight();
    }

    void moveLeft() {
        super.onBackPressed();
        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);
    }

    void moveRight() {
        super.onBackPressed();
        overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);
    }

    private Handler mNetworkExplainHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_NETWORK_EXPLAIN_START:
                    boolean show = false;
                    if (progressDialog == null) {
                        show = true;
                    } else if (!progressDialog.isShowing()) {
                        show = true;
                    }
                    if (show) {
                        progressDialog = ProgressDialog.show(mContext, null,
                                getString(R.string.msg_wait), true, true);
                    }
                    break;
                case WHAT_NETWORK_EXPLAIN_DONE:
                    progressDialog.dismiss();
                    break;
                default:
                    break;
            }
        }
    };

    private Handler mPlayAudioHandler = new Handler() {
        private boolean success;

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case WHAT_PLAY_AUDIO_START:
                    success = false;
                    boolean show = false;
                    if (progressDialog == null) {
                        show = true;
                    } else if (!progressDialog.isShowing()) {
                        show = true;
                    }

                    if (show) {
                        progressDialog = ProgressDialog.show(mContext, null,
                                getString(R.string.msg_wait), true, true);
                    }
                    break;
                case WHAT_PLAY_AUDIO_DONE:
                    removeMessages(WHAT_PLAY_AUDIO_TIMEOUT);
                    progressDialog.dismiss();
                    success = true;
                    break;
                case WHAT_PLAY_AUDIO_TIMEOUT:
                    if (!success) {
                        progressDialog.dismiss();
                        Toast.makeText(mContext, R.string.msg_audio_error, Toast.LENGTH_SHORT)
                                .show();
                        player.reset();
                    }
                    break;
                default:
                    break;
            }
        }

    };

    public void onEndDownload(int result) {
        switch (result) {
            case DictSource.OnUpdateNotifyListener.FETCH_SUCCESS:
                break;
            case DictSource.OnUpdateNotifyListener.NETWORK_ERROR:
                showNetworkNotAvailableToast();
                break;
        }
    }

    private void showNetworkNotAvailableToast() {
        Toast.makeText(this, R.string.msg_error_network, Toast.LENGTH_SHORT).show();
    }

    public void onMoveBegin(int mCurrentView) {
        PANEL_CURRENT = mCurrentView;
    }

    public void onMoveEnd(int mCurrentView) {
        changeStatus();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, Menu.FIRST + 1, Menu.NONE, R.string.add_to_words).setIcon(
                android.R.drawable.ic_input_add);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        super.onOptionsItemSelected(item);
        mSQL = new SQLiteNewWords(this);
        mSQL.save(mNewWord);
        Toast.makeText(this, R.string._success_add, Toast.LENGTH_SHORT).show();
        return true;
    }

}
